<html>
<body>
<h1>Lifecycle Plugin</h1>
<p>
    The lifecycle plugin defines abstract targets defining the build lifecycle of a module,
    including compile, test, package and install. Other plugins implement such targets,
    providing the actual functionality.
</p>

<div id="content-before">
    <p>The lifecycle plugin is central to building projects with quokka. The plugin itself is entirely
        abstract. i.e. including the plugin on it's own doesn't actually do anything that effects your project files.
        Instead, it defines an abstract framework that other plugins implement. For example, the lifecycle
        plugin defines the <i>abstract</i> <tt>compile</tt> target that Javac plugin <i>implements</i>.
    </p>

    <h2>The Lifecycle</h2>
    <p>The lifecycle targets are organised as a chain of dependencies. The following lists the
        targets in order. If you execute any target in the list, all targets that proceed it get executed.</p>

    <ul>
        <li style="margin:0">initialise</li>
        <li style="margin:0">generate-sources</li>
        <li style="margin:0">process-sources</li>
        <li style="margin:0">generate-resources</li>
        <li style="margin:0">process-resources</li>
        <li style="margin:0">compile</li>
        <li style="margin:0">process-compiled</li>
        <li style="margin:0">instrument-compiled</li>
        <li style="margin:0">generate-test-sources</li>
        <li style="margin:0">process-test-sources</li>
        <li style="margin:0">generate-test-resources</li>
        <li style="margin:0">process-test-resources</li>
        <li style="margin:0">test-compile</li>
        <li style="margin:0">test</li>
        <li style="margin:0">package</li>
        <li style="margin:0">initialise-integration-test</li>
        <li style="margin:0">integration-test-impl</li>
        <li style="margin:0">finalise-integration-test</li>
        <li style="margin:0">integration-test</li>
        <li style="margin:0">verify</li>
        <li style="margin:0">install</li>
    </ul>
    <p>For example, if you execute <tt>process-sources</tt>, the project build sequence will be
    <tt>initialise</tt>, then <tt>generate-sources</tt>, followed by <tt>process-sources</tt></p>

    <p>Continuing the example of Javac plugin, let's consider what happens when the Javac plugin implements
    <tt>compile</tt>. If you consult the Javac plugin documentation you will see that it declares
    a target <tt>javac:compile</tt> that implements <tt>lifecycle:compile</tt>. When quokka encounters
    an <i>implements</i> declaration during initialisation, it rewires the target dependencies as follows:</p>
    <ul>
        <li style="margin:0; list-style:square">The implementing target is added as a dependency of
        the abstract target.</li>
        <li style="margin:0; list-style:square">Any dependencies of the abstract target are moved
            to become dependencies of the implementing target.</li>
    </ul>
    <p>So in the case adding the Javac plugin, the modified build sequence becomes:</p>
    <ul>
        ...
        <li style="margin:0">process-resources</li>
        <li style="margin:0">javac:compile</li>
        <li style="margin:0">compile</li>
        ...
    </ul>
    <p>This mechanism is quite flexible as it allows the user to continue using the abstract target
    name of <tt>compile</tt> regardless of what implementations are available. However, it also
    exposes the <tt>javac:compile</tt> to the user for direct access if desired.</p>

    <p>There is one detail missing for the above description, namely pre-targets. If you look at the real
    sequence below you will notice that every lifecycle target is proceed by a target of the same
    name prefixed by <tt>pre-</tt>.</p>
    <p>So the real build sequence is actually:</p>
    <ul>
        ...
        <li style="margin:0">pre-process-resources</li>
        <li style="margin:0">process-resources</li>
        <li style="margin:0">pre-compile</li>
        <li style="margin:0">javac:compile</li>
        <li style="margin:0">compile</li>
        ...
    </ul>
    <p>Why the extra targets? They are there so the users can reliably insert additional ad hoc targets
    into the build sequence. For example, let's assume the user wants insert a target between <tt>compile</tt>
    and <tt>process-resources</tt></p>
    <p>Without the pre-targets, they would have to refer to the javac target as follows:</p>
    <pre>&lt;target name="mytarget" depends="process-resources" dependency-of="javac:compile"&gt;</pre>
    <p>This is problematic because there may be no implementations, or multiple implementations (whose order is undefined),
        or may break if an additional implementation is added.
    Using pre-targets, these problems are avoided completely with the delcaration becoming:</p>
    <pre>&lt;target name="mytarget" depends="process-resources" dependency-of="pre-compile"&gt;</pre>

    <h2>Project Paths</h2>
    <p>The other important aspect to the lifecycle plugin is that it defines some important project paths
        and controls how they are merged. The following paths are defined:</p>
    <table>
        <tr>
            <td><b>id</b></td>
            <td><b>Description</b></td>
            <td><b>Descends Default</b></td>
        </tr>
        <tr>
            <td>compile</td>
            <td>Compilation class path</td>
            <td>false</td>
        </tr>
        <tr>
            <td>test-compile</td>
            <td>Tests compilation class path</td>
            <td>false</td>
        </tr>
        <tr>
            <td>test</td>
            <td>Tests runtime class path</td>
            <td>true</td>
        </tr>
        <tr>
            <td>itest</td>
            <td>Integration tests runtime class path</td>
            <td>true</td>
        </tr>
        <tr>
            <td>runtime</td>
            <td>Runtime class path</td>
            <td>true</td>
        </tr>
    </table>
    <p>The <i>descends default</i> value controls whether transitive dependendencies (dependencies of dependencies)
    are added when you add a dependency to a path. See <a href="http://quokka.ws/project-reference.html#paths">here</a> for
    more information.</p>
    <p>Targets merge the above paths as follows:</p>
    <table>
        <tr>
            <td><b>Target</b></td>
            <td><b>Merged Paths</b></td>
        </tr>
        <tr>
            <td>compile</td>
            <td>compile</td>
        </tr>
        <tr>
            <td>test-compile</td>
            <td>test-compile, compile</td>
        </tr>
        <tr>
            <td>test</td>
            <td>test, test-compile, compile, ${q.lifecycle.testPaths}*</td>
        </tr>
        <tr>
            <td>integration-test-impl</td>
            <td>itest, test, test-compile, compile, ${q.lifecycle.itestPaths}*</td>
        </tr>
    </table>
    <p>* The <tt>q.lifecycle.testPaths/itestPaths</tt> entries are an elaborate means of adding the
        runtime paths to the merged testing paths. By default, <tt>q.lifecycle.testPaths/itestPaths</tt> are
        defined to be the value of <tt>q.project.exportedPaths</tt>. <tt>q.project.exportedPaths</tt>
    contains any project paths that you are exporting to the repository, which is usually <tt>runtime</tt>.</p>
    <p>Why all this indirection? The reason is that quokka (and it's repositories) supports multiple runtime paths.
    By default Quokka defines a path with an id of <tt>runtime</tt>. However, this is just a convenience
    and users are free to ignore it. </p>
    <p><b>Notes for Maven users:</b></p>
    <p>There are some important differences between how Quokka and Maven handle project paths:</p>
    <ul>
        <li style="margin:0; list-style:square">In Maven you do not actually assign dependencies to
        paths. Instead you set <i>scopes</i> and Maven attempts to derive the paths based on the scopes.</li>
        <li style="margin:0; list-style:square">Maven's <tt>compile</tt> scope includes transitive
        dependencies, where adding a dependency to Quokka's <tt>compile</tt> path does not. Quokka's approach
        is the correct approach as it forces you to declare all source code dependencies explicitly. Maven
            states that it doesn't do this due to cases where extending an abstract class requires classes
            not referenced in the source. This is true, however Quokka allows you to add such dependencies
            as options when required. e.g. in this example, bootstrap-util is for compilation, but not actually referenced in the source
            <pre>&lt;dependency group="quokka.core.plugin-spi" version="?" paths="compile(bootstrap-util), runtime"/&gt;</pre>
        </li>
        <li style="margin:0; list-style:square">Quokka splits the Maven test scope into <tt>test-compile</tt>,
        <tt>test</tt> and <tt>itest</tt>. Again, this forces explicit declaration of all source dependencies. If you don't like
        this, see the next section for overriding the defaults.</li>
    </ul>
    <p><b>Overriding the defaults</b></p>
    <p>The defaults in Quokka are designed to be strict to enforce all dependencies to be declared. However,
    you can override the defaults simply if you don't like them using <a href="http://quokka.ws/project-reference.html#path-specs">path specifications</a>.
        Here's some examples:</p>
    <ul>
        <li style="margin:0; list-style:square"><b>Excluding transitive dependencies for runtime paths:</b> To
        do this, just append a <tt>+</tt> character after the path name. e.g.
            <pre>&lt;dependency group="apache.ant" version="1.7.1" <b>paths="runtime+"</b>/&gt;</pre>
        </li>
        <li style="margin:0; list-style:square"><b>Including transitive dependencies for test paths:</b> To
        do this, just append a <tt>&lt;</tt> after the path name. e.g.
            <pre>&lt;dependency group="apache.ant" version="1.7.1" <b>paths="test-compile&lt;"</b>/&gt;</pre>
        </li>
    </ul>
</div>
</body>
</html>